<?php

namespace App\Console\Commands;

use App\Traits\ChatBase;
use Illuminate\Console\Command;
use Swoole\WebSocket\Server;

class WSChatRoom extends Command
{
    use ChatBase;
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'command:ws-chat-room';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'websocket 聊天室逻辑';

    public $ws = null;

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
        //创建WebSocket Server对象，监听0.0.0.0:9502端口
        $this->ws = new Server(env('APP_DOMAIN'), 9502 ,SWOOLE_PROCESS,SWOOLE_SOCK_TCP/*| SWOOLE_SSL*/);

        $this->ws->set([
            'task_worker_num' => 4,
            // http2服务器需要引入 ssl 证书
            /*'ssl_cert_file' => __DIR__ . '/../static/ssl.crt',
            'ssl_key_file' => __DIR__ . '/../static/ssl.key',*/
        ]);
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $this->ws->on('open', [$this, 'onOpen']);
        $this->ws->on('message', [$this, 'onMessage']);
        $this->ws->on('task', [$this, 'onTask']);
        $this->ws->on('finish', [$this, 'onFinish']);
        $this->ws->on('close', [$this, 'onClose']);
        $this->ws->start();
    }

    public function onOpen($ws, $request)
    {
        $this->start($request->get['access_token'], $request->get['type'], $ws, $request->fd);
    }

    public function onMessage($ws, $frame)
    {
        $this->switchBoard($ws, $frame);
    }

    public function onTask($ws, $task_id, $src_worker_id, $data)
    {
        return $data;  // return to onFinish
    }

    public function onFinish($ws, $task_id, $data)
    {
    }

    public function onClose($ws, $fd)
    {
        $uid = $this->getBindUid($ws, $fd);
        if(!empty($uid)) {
            $data = $this->getSocket($uid);
            foreach ($data['fd'] as $key => $value) {
                if($fd == $value) {
                    unset($data['fd'][$key]);
                }
            }
            $this->setSocket($uid, $data);

        }
    }
}
